﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Projectile.cs" company="">
//   
// </copyright>
// <summary>
// An object launched to an enemy.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

/*
 * Author: Barbara Carboni
 * Created: 17-11-2011 
 * Revised: 21-11-2011 Add the 'direction'
 * Revised: 04-12-2011 Modify the method 'hit' with the 'projectile'
 */

namespace ITU_vs_Zombies.Stuff
{
    using System;
    using System.Diagnostics.Contracts;

    using ITU_vs_Zombies.Movement;

    using Microsoft.Xna.Framework;

    /// <summary>
    /// An object launched to an enemy.
    /// </summary>
    [Serializable]
    public class Projectile : ExtraObject
    {
        #region Constants and Fields

        /// <summary>
        /// The damage.
        /// </summary>
        private uint damage;

        /// <summary>
        /// The direction.
        /// </summary>
        private MovementsEnum direction;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="Projectile"/> class.
        /// </summary>
        /// <param name="image">
        /// The Image. 
        /// </param>
        /// <param name="numberFrames">
        /// The number of frames. 
        /// </param>
        /// <param name="numberFloor">
        /// The number of floor. 
        /// </param>
        /// <param name="position">
        /// The position. 
        /// </param>
        /// <param name="damage">
        /// The damage. 
        /// </param>
        /// <param name="direction">
        /// The direction. 
        /// </param>
        /// <param name="speed">
        /// The speed. 
        /// </param>
        /// <param name="sound">
        /// The sound.
        /// </param>
        public Projectile(
            string image, 
            uint numberFrames, 
            int numberFloor, 
            Vector2 position, 
            uint damage, 
            MovementsEnum direction, 
            int speed, 
            string sound)
            : base(image, numberFrames, numberFloor, position, sound)
        {
            Contract.Requires(image != null);
            Contract.Requires(sound != null);
            Contract.Requires(position.X >= 0 && position.Y >= 0);
            Contract.Requires(numberFrames > 0);
            Contract.Requires(damage > 0);
            Contract.Requires(speed > 0);
            Contract.Requires(direction == MovementsEnum.Left || direction == MovementsEnum.Right);
            this.Damage = damage;
            this.Direction = direction;
            if (direction == MovementsEnum.Left)
            {
                this.Speed = -speed;
            }
            else
            {
                this.Speed = speed;
            }
        }

        #endregion

        #region Public Properties

        /// <summary>
        /// Gets Damage.
        /// </summary>
        public uint Damage
        {
            get
            {
                Contract.Ensures(Contract.Result<uint>() > 0);
                return this.damage;
            }

            private set
            {
                this.damage = value;
            }
        }

        /// <summary>
        /// Gets Direction.
        /// </summary>
        public MovementsEnum Direction
        {
            get
            {
                Contract.Ensures(
                    Contract.Result<MovementsEnum>() == MovementsEnum.Left
                    || Contract.Result<MovementsEnum>() == MovementsEnum.Right);
                return this.direction;
            }

            private set
            {
                Contract.Requires(value == MovementsEnum.Left || value == MovementsEnum.Right);
                this.direction = value;
            }
        }

        /// <summary>
        /// Gets Speed.
        /// </summary>
        public int Speed { get; private set; }

        #endregion

        #region Public Methods

        /// <summary>
        /// The update.
        /// </summary>
        /// <param name="gameTime">
        /// The game time.
        /// </param>
        /// <param name="position">
        /// The position.
        /// </param>
        public override void Update(GameTime gameTime, Vector2 position)
        {
            this.Animation.Flip(this.Direction);
            this.Position = new Vector2(this.Position.X + this.Speed, this.Position.Y);
            base.Update(gameTime, position);
        }

        #endregion
    }
}